package UnitTest;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Auther: dingtian
 * @Date: 2020 17 38
 * @Description: 当队列为空的时候，获取队列元素的线程会阻塞，直到添加元素进入，当队列为满的时候，添加队列元素的线程会阻塞，直到元素被移除
 */
public class BoundedQueue<T> {
    private Object[] items;
    private int addIndex, removeIndex, count;
    private Lock lock = new ReentrantLock();
    private Condition notEmpty = lock.newCondition();
    private Condition notFull = lock.newCondition();

    public BoundedQueue(int size) {
        items = new Object[size];
    }

    public void add(T t) {
        lock.lock();
        try {
            if (count == items.length) {
                notFull.wait();
            }
            items[addIndex] = t;
            addIndex++;
            count++;
            notEmpty.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public T remove() {
        lock.lock();
        try {
            while (count == 0) {
                notEmpty.await();
            }
            Object item = items[removeIndex];
            --count;
            notFull.signal();
            return (T) item;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return null;
    }

    public T get() {
        lock.lock();
        try {
            while (count == 0) {
                notEmpty.await();
            }
            return (T) items[0];
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return null;
    }


}
